import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * java 时间工具类
 * @Author zhangkaiqiang
 * @Date 2019/3/24  14:25
 * @Description TODO
 */
public class TimeUtils {




    /**
     * 多线程环境下SimpleDateFormat存在线程安全问题，需要使用synchronized进行控制
     */
    private static final SimpleDateFormat SIMPLE_DATE_FORMAT=new SimpleDateFormat("yyyy-MM-dd");

    private static final  DateTimeFormatter DATE_TIME_FORMATTER=DateTimeFormatter.ofPattern("yyyy-MM-dd");

    /**
     * java.sql.date to java.util.date
     * @param date java.sql.date
     * @return Date
     */
    public static Date sqlDateToUtilDate(java.sql.Date date){
        synchronized (SIMPLE_DATE_FORMAT){
            SIMPLE_DATE_FORMAT.format(date);
        }
        return  new Date(date.getTime());

    }

    /**
     * java.util.date to java.sql.date
     * @param date java.util.date
     * @return Timestamp
     */
    public static Timestamp utilsDateToSqlDate(Date date){
        synchronized (SIMPLE_DATE_FORMAT){
            SIMPLE_DATE_FORMAT.format(date);
        }
        return new Timestamp(date.getTime());
    }

    /**
     * java.util.Date --> java.time.LocalDateTime
     * @param date
     * @return
     */
    public static LocalDateTime utilDateToLocalDateTime(Date date){
        synchronized (SIMPLE_DATE_FORMAT){
            SIMPLE_DATE_FORMAT.format(date);
        }
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
        return  localDateTime;
    }

    /**
     * Java.util.Date --->java.time.LocalDate
     * @param date java.util.date
     * @return LocalDate
     */
    public static LocalDate utilDateToLocalDate(Date date){
        LocalDateTime localDateTime= TimeUtils.utilDateToLocalDateTime(date);
        return  localDateTime.toLocalDate();
    }

    /**
     * java.util.Date -->java.time.LocalTime
     * @param date java.util.date
     * @return LocalTime
     */
    public static LocalTime utilDateToLocalTime(Date date){
        LocalDateTime localDateTime= TimeUtils.utilDateToLocalDateTime(date);
        return  localDateTime.toLocalTime();
    }

    /**
     * java.time.LocalDateTime -->java.util.Date
     * @param localDateTime java.time.LocalDateTime
     * @return Date
     */
    public static Date localDateTimeToDate(LocalDateTime localDateTime){
        ZoneId zone = ZoneId.systemDefault();
        Instant instant=localDateTime.atZone(zone).toInstant();
        Date date=Date.from(instant);
        synchronized (SIMPLE_DATE_FORMAT){
            SIMPLE_DATE_FORMAT.format(date);
        }
        return  date;
    }

    /**
     * java.time.LocalDate -->java.util.Date
     * @param localDate java.time.LocalDate
     * @return java.util.Date
     */
    public static Date localDateToUtilDate(LocalDate localDate){
        ZoneId zone = ZoneId.systemDefault();
        Instant instant=localDate.atStartOfDay(zone).toInstant();
        Date date=Date.from(instant);
        synchronized (SIMPLE_DATE_FORMAT){
            SIMPLE_DATE_FORMAT.format(date);
        }
        return  date;
    }


    /**
     * java.sql.Date -->java.time.LocalDateTime
     * @param date java.util.date
     * @return LocalDateTime
     */
    public static LocalDateTime sqlDateToLocalDateTime(java.sql.Date date){
        Date udate= TimeUtils.sqlDateToUtilDate(date);
        return TimeUtils.utilDateToLocalDateTime(udate);

    }

    /**
     * java.time.LocalDateTime -->java.sql.Timestamp
     * @param localDateTime
     * @return Timestamp
     */
    public static Timestamp localDateTimeToSqlDate(LocalDateTime localDateTime){
        Date udate= TimeUtils.localDateTimeToDate(localDateTime);
        return TimeUtils.utilsDateToSqlDate(udate);
    }
}
